package cn.chiship.framework.upms.biz.user.service.impl;

import cn.chiship.framework.common.constants.CommonCacheConstants;
import cn.chiship.framework.upms.biz.user.pojo.vo.UpmsUserOnlineVo;
import cn.chiship.framework.upms.biz.user.service.UpmsUserOnlineService;
import cn.chiship.sdk.cache.service.RedisService;
import cn.chiship.sdk.cache.service.UserCacheService;
import cn.chiship.sdk.cache.vo.CacheOrganizationVo;
import cn.chiship.sdk.cache.vo.CacheUserVO;
import cn.chiship.sdk.core.base.BaseResult;
import cn.chiship.sdk.core.base.constants.BaseCacheConstants;
import cn.chiship.sdk.core.useragent.UserAgentUtil;
import cn.chiship.sdk.core.util.StringUtil;
import cn.chiship.sdk.core.util.ip.AddressUtils;
import cn.chiship.sdk.framework.pojo.vo.PageVo;
import cn.chiship.sdk.framework.util.ServletUtil;
import org.springframework.stereotype.Service;
import springfox.documentation.annotations.ApiIgnore;

import javax.annotation.Resource;
import java.util.*;

/**
 * @author lijian
 */
@Service
public class UpmsUserOnlineServiceImpl implements UpmsUserOnlineService {

	@Resource
	RedisService redisService;

	@Resource
	UserCacheService userCacheService;

	@Override
	public BaseResult page(Long page, Long limit, String ip, String userName) {
		Set<String> keys = redisService
				.keys(CommonCacheConstants.buildKey(BaseCacheConstants.REDIS_ONLINE_USER_PREFIX) + ":*");
		Iterator<String> iterator = keys.iterator();
		List<UpmsUserOnlineVo> userOnlineVos = new ArrayList<>();
		while (iterator.hasNext()) {
			userOnlineVos.add((UpmsUserOnlineVo) redisService.get(iterator.next()));
		}
		userOnlineVos.sort(new Comparator<UpmsUserOnlineVo>() {
			@Override
			public int compare(UpmsUserOnlineVo o1, UpmsUserOnlineVo o2) {
				if (o1.getLoginTime() > o2.getLoginTime()) {
					return -1;
				}
				else if (o1.getLoginTime() < o2.getLoginTime()) {
					return 1;
				}
				else {
					return 0;
				}
			}
		});
		PageVo pageVo = new PageVo();
		pageVo.setCurrent(page);
		pageVo.setSize(limit);
		pageVo.setTotal(Long.valueOf(userOnlineVos.size()));
		pageVo.setRecords(userOnlineVos);
		return BaseResult.ok(pageVo);
	}

	@Override
	public BaseResult loginUserToUserOnline(String token, @ApiIgnore CacheUserVO userVO, String ip) {
		UserAgentUtil userAgent = UserAgentUtil.parseUserAgentString(ServletUtil.getRequest().getHeader("User-Agent"));
		UpmsUserOnlineVo userOnlineVo = new UpmsUserOnlineVo();
		userOnlineVo.setSessionId(userVO.getSessionId());
		userOnlineVo.setToken(token);
		userOnlineVo.setUserName(userVO.getUsername());
		CacheOrganizationVo organizationVo = userVO.getCacheOrganizationVo();
		if (!StringUtil.isNull(organizationVo)) {
			userOnlineVo.setOrgName(organizationVo.getName());
		}
		userOnlineVo.setIp(ip);
		if (!StringUtil.isNull(userAgent.getBrowserVersion())) {
			userOnlineVo.setBrowser(
					userAgent.getBrowser().getName() + "(" + userAgent.getBrowserVersion().getVersion() + ")");
		}
		else {
			userOnlineVo.setBrowser(userAgent.getBrowser().getName());
		}
		userOnlineVo.setOs(userAgent.getOperatingSystem().getName());
		userOnlineVo.setLoginTime(System.currentTimeMillis());
		userOnlineVo.setLoginAddress(AddressUtils.getRealAddressByIp(ip));
		redisService.set(CommonCacheConstants.buildKey(BaseCacheConstants.REDIS_ONLINE_USER_PREFIX) + ":"
				+ userOnlineVo.getSessionId(), userOnlineVo);
		return BaseResult.ok();
	}

	@Override
	public BaseResult forceLogout(String sessionId) {
		String key = CommonCacheConstants.buildKey(BaseCacheConstants.REDIS_ONLINE_USER_PREFIX) + ":" + sessionId;
		UpmsUserOnlineVo userOnlineVo = (UpmsUserOnlineVo) redisService.get(key);
		redisService.del(key);
		if (!StringUtil.isNull(userOnlineVo)) {
			userCacheService.removeUserByToken(userOnlineVo.getToken());
		}
		return BaseResult.ok();
	}

}
